﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BlackBBS.Models.Data;
using BlackBBS.Infrastructure.Logging;
using System.IO;
using BlackBBS.Infrastructure.TelnetProtocol;

namespace BlackBBS.Menus
{
    public class LogOn : MenuBase
    {
        public LogOn()
        {
        }

        public override void SendMenu()
        {
            this.SendLoginScreens();            

            var handled = false;
            var looper = 0;
            while(!handled && looper < 5)
            {
                handled = this.HandleResponse(this.Connection.SendScript("LOGON.MNU"));
                if (!handled)
                {
                    this.Connection.SendTemplate(TelnetClient.ErrorMessageTemplate, MessageStrings.InvalidCredentials);
                    this.Connection.Pause(5);
                    this.SendLoginScreens();
                }
                looper++;
            }
            if (handled == false)
            {
                base.DoLogOff(true);
            }
            else
            {
                this.Connection.SendTemplate(TelnetClient.MessageTemplate, MessageStrings.AccessGranted);
                this.LogDebug(string.Format("User [{0}] Succesfully Logged In", this.Connection.Session.User.Login));
                this.Connection.Pause(1);

                this.SendPostLoginScreens();

                // Now send to Main Menu
                var main = new BlackBBS.Menus.Main
                {
                    Connection = this.Connection
                };
                main.Init();
                main.SendMenu();
            }
        }

        /// <summary>
        /// This is sent before the User Logs in
        /// </summary>
        void SendLoginScreens()
        {
            this.Connection.ClearScreen();

            // Send the Ansi File
            this.Connection.SendFile("CONNECT.ANS");
        }

        /// <summary>
        /// This is called after the user is authenticated
        /// </summary>
        /// <param name="client"></param>
        void SendPostLoginScreens()
        {
            var sentFiles = false;
            // Send all (any) of the post logon ans files
            foreach (string file in Directory.GetFiles(this.Connection.ServerSettings.MenuFullPath(string.Empty), "LOGON*.ANS").OrderBy(x => x.ToString()))
            {
                this.Connection.SendFile(file);
                sentFiles = true;
            }
            if (sentFiles)
            {                
                this.Connection.SendTemplate(TelnetClient.MessageTemplate, MessageStrings.AnyKeyToContinue);
            }
        }

        string StatsScreen()
        {
            return "This is the Stats Screen";
        }

        public bool HandleResponse(Dictionary<string, string> response)
        {
            if (response == null || response.Count == 0)
            {
                return false;
            }

            var key = response.First().Key;
            var value = response.First().Value;

            if (string.IsNullOrEmpty(key))
            {
                return false;
            }
            switch (key.ToLower())
            {
                case "new":
                    return this.ShowSignUp();
                default:
                    return this.DoLogin(response["username"], response["password"]);
            }
        }

        bool ShowSignUp()
        {
            this.Connection.SendString("New Signup Here");

            // Confirm "Login as a new User?" (default "No")

            // Display "NEWUSER.MSG"

            // Confirm "Continue login as new user?" (default "Yes")

            // Display "NEWUSER1.MGS"

            // "Enter width (# columns) of your screen (32-132): 80"

            // "Enter length (# rows) of your screen (4-50): 24"

            // "Enter your first & last name:"

            // "Where are you calling from?" (List "1. United States", "2. Canada", "3. Other country")

            // "Enter your city name:"

            // "Enter your 2-letter state abbrevation:"

            // "Date format type (1-3):" (List "1. MM/DD/YYYY (12/31/2011)", "2. DD/MM/YYYY (31/12/2011)", "3. YYYY/MM/DD (2011/12/31)")

            // "Enter list selection (NOTES1.TXT, 1-12):" (list of computer types)

            // "Enter list selection (NOTES2.TXT, 1-10):" (list of modem speeds)

            // "Pause when screen is full?" (default "Yes")

            // "Clear screen between messages?" (default "Yes")

            // "Extended input for menus?" (default "No")

            // "Hotkeys during menu/screen display?" (default "Yes")

            // Display "PASSWORD.MSG"

            // "Your password must have a length between X and XX characters."
            // "Enter Password:"
            // "Re-enter Password for verification"

            // Ask for username then check if unique

            // Show menu of all user options (see screen snapshot)
            

            // Save user account

            // Display "USERINFO.MSG"





            return false;
        }

        bool DoLogin(string username, string password)
        {
            var user = User.GetUserByLogin(this.Connection.Repository.Users, username);
            if (user == null)
            {
                return false;
            }
            var authenticated = user.AuthenticateUser(password);
            if (authenticated)
            {
                this.Connection.Session.User = user;
                this.Connection.Session.Created = DateTime.Now;
                this.Connection.Session.Id = this.Connection.Repository.Sessions.NextId();
                this.Connection.Session.CurrentArea = Enums.Area.LogOn;              

                var fromAddress = this.Connection.ClientRemoteEndPoint.ToString();
                this.Connection.Session.User.DoLoginEvents(this.Connection.Repository, fromAddress);
            }
            return authenticated;
        }
    }
}
